﻿'*******************************************************************************************
'* Copyright Brügmann Software GmbH, Papenburg
'* Author: Björn Kremer
'* Contact: codeplex<at>patorg.de
'* 
'* VB.CMIS is a VB.NET implementation of the Content Management Interoperability Services (CMIS) standard
'*
'* This file is part of VB.CMIS.
'* 
'* VB.CMIS is free software: you can redistribute it and/or modify
'* it under the terms of the GNU Lesser General Public License as published by
'* the Free Software Foundation, either version 3 of the License, or
'* (at your option) any later version.
'* 
'* VB.CMIS is distributed in the hope that it will be useful,
'* but WITHOUT ANY WARRANTY; without even the implied warranty of
'* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
'* GNU Lesser General Public License for more details.
'* 
'* You should have received a copy of the GNU Lesser General Public License
'* along with VB.CMIS. If not, see <http://www.gnu.org/licenses/>.
'*******************************************************************************************
Imports CMISObjectModel
''' <summary>
''' The provider is not designed for running in a productive szenario.
''' The provider isn't thread-safe
''' The provider doesn't implement all avilable functions
''' The provider doesn't support all request parameters
''' The provider doesn't use the full capacity of the object modell.
''' The provider isn't optimized
''' </summary>
''' <remarks></remarks>
Public Class Provider
   Implements CMISObjectModel.IProvider

   Private Shared _cmisSampleData As New Dictionary(Of String, CMISSampleData)
   Private Shared _sampleTypes As New Dictionary(Of String, TypeData)

   Public Const ConstNamespace As String = "http://example.org"

   ''' <summary>
   ''' This option will enable all capabilities. This will cause logical errors.
   ''' </summary>
   ''' <remarks></remarks>
   Public Const EnableAllCapabilitiesForTCKTest As Boolean = False

   Shared Sub New()
      SetTypes()


      Dim rootFolder As New CMISSampleData("ROOTFOLDER", _sampleTypes(TypeData.RootFolderType)) With {.Title = "ROOTFOLDER", .Path = "/"}
      _cmisSampleData.Add("ROOTFOLDER", rootFolder)

      Dim doc1 As New CMISSampleData("SampleDocument1", _sampleTypes(TypeData.Document1Type)) With {.Title = "SampleDocument1"}
      doc1.Value3 = CDec(34324324.234324321)
      doc1.Mimetype = "text/plain"
      doc1.ContentStream = My.Resources.sample


      _cmisSampleData.Add("SampleDocument1", doc1)
      rootFolder.AddChild("SampleDocument1", doc1)

      Dim folder1 As New CMISSampleData("SampleFolder1", _sampleTypes(TypeData.Folder1Type)) With {.Title = "SampleFolder1", .Path = "/SampleFolder1"}
      _cmisSampleData.Add("SampleFolder1", folder1)
      rootFolder.AddChild("SampleFolder1", folder1)

      Dim doc2 As New CMISSampleData("SampleDocument2", _sampleTypes(TypeData.Document1Type)) With {.Title = "SampleDocument2"}
      _cmisSampleData.Add("SampleDocument2", doc2)
      folder1.AddChild("SampleDocument2", doc2)

      Dim rel1 As New CMISSampleData("SampleRelationship1", _sampleTypes(TypeData.Relationship1Type)) With {.Title = "SampleRelationship1", .SourceId = "SampleDocument1", .TargetId = "SampleDocument2"}
      _cmisSampleData.Add("SampleRelationship1", rel1)
      doc1.Relationships.Add(rel1.Id, rel1)
      doc2.Relationships.Add(rel1.Id, rel1)
   End Sub
   Private Shared Sub SetTypes()

      Dim folder1 As New TypeData(TypeData.TypeEnum.Folder1, New Dictionary(Of String, TypeData))
      _sampleTypes.Add(folder1.Definition.Id, folder1)

      Dim document1 As New TypeData(TypeData.TypeEnum.Document1, New Dictionary(Of String, TypeData))
      _sampleTypes.Add(document1.Definition.Id, document1)

      Dim type As New TypeData(TypeData.TypeEnum.RootDocument, New Dictionary(Of String, TypeData) From {{document1.Definition.Id, document1}})
      _sampleTypes.Add(type.Definition.Id, type)

      type = New TypeData(TypeData.TypeEnum.RootFolder, New Dictionary(Of String, TypeData) From {{folder1.Definition.Id, folder1}})
      _sampleTypes.Add(type.Definition.Id, type)

      Dim rel1Type As New TypeData(TypeData.TypeEnum.Relationship1, New Dictionary(Of String, TypeData))
      _sampleTypes.Add(rel1Type.Definition.Id, rel1Type)


      type = New TypeData(TypeData.TypeEnum.RootRelationship, New Dictionary(Of String, TypeData) From {{rel1Type.Definition.Id, rel1Type}})
      _sampleTypes.Add(type.Definition.Id, type)


      type = New TypeData(TypeData.TypeEnum.RootPolicy, New Dictionary(Of String, TypeData))
      _sampleTypes.Add(type.Definition.Id, type)
   End Sub


   Public Function ApplyACL(repositoryId As String, id As String, aclPropagation As CMISObjectModel.Enums.ACLPropagationEnum?, rawData As System.Xml.XmlDocument, parsedData As CMISObjectModel.CMISObjects.Acl) As CMISObjectModel.CMISObjects.Acl Implements CMISObjectModel.IProvider.ApplyACL
      Throw New System.ServiceModel.Web.WebFaultException(Net.HttpStatusCode.NotImplemented)
   End Function

   Public Function ApplyPolicy(repositoryId As String, id As String, rawData As System.Xml.XmlDocument, parsedData As CMISObjectModel.CMISObjects.CMISReceiptObject) As CMISObjectModel.Atom.CMISAtomEntryCmisObject Implements CMISObjectModel.IProvider.ApplyPolicy
      Throw New System.ServiceModel.Web.WebFaultException(Net.HttpStatusCode.NotImplemented)
   End Function

   Public Function CheckOut(repositoryId As String, rawData As System.Xml.XmlDocument, parsedData As CMISObjectModel.CMISObjects.CMISReceiptObject) As CMISObjectModel.Atom.CMISAtomEntryCmisObject Implements CMISObjectModel.IProvider.CheckOut
      Throw New System.ServiceModel.Web.WebFaultException(Net.HttpStatusCode.NotImplemented)
   End Function

   Public Function CreateOrMoveObject(repositoryId As String, id As String, sourceFolderId As String, versioningState As CMISObjectModel.Enums.VersioningStateEnum?, rawData As System.Xml.XmlDocument, parsedData As CMISObjectModel.CMISObjects.CMISReceiptObject) As CMISObjectModel.Atom.CMISAtomEntryCmisObject Implements CMISObjectModel.IProvider.CreateOrMoveObject
      If String.IsNullOrEmpty(sourceFolderId) Then
         Dim typeProp As Properties.ICMISProperty = parsedData.GetPropertyByDefinitionId("cmis:objectTypeId", False)
         Dim nameProp As Properties.ICMISProperty = parsedData.GetPropertyByDefinitionId("cmis:name", False)
         If typeProp IsNot Nothing AndAlso typeProp.GetType Is GetType(Properties.CmisPropertyId) Then
            Dim typedTypeProp As Properties.CmisPropertyId = DirectCast(typeProp, Properties.CmisPropertyId)
            Dim objType As TypeData.BaseTypeEnum = _sampleTypes(typedTypeProp.Values(0)).BaseType

            If nameProp IsNot Nothing AndAlso nameProp.GetType Is GetType(Properties.CmisPropertyString) Then
               Dim typedNameProp As Properties.CmisPropertyString = DirectCast(nameProp, Properties.CmisPropertyString)
               Dim parent As CMISSampleData = _cmisSampleData(id)
               If objType = TypeData.BaseTypeEnum.RootDocument Then
                  Dim newObj As New CMISSampleData(Guid.NewGuid.ToString, _sampleTypes(TypeData.Document1Type)) With {.Title = typedNameProp.Values(0)}
                  If parsedData.Content IsNot Nothing Then
                     newObj.ContentStream = parsedData.Content.Content
                     newObj.Mimetype = parsedData.Content.MediaType
                  End If
                  InnerUpdateProperties(parsedData, newObj)
                  parent.AddChild(newObj.Id, newObj)
                  _cmisSampleData.Add(newObj.Id, newObj)
                  Return GetAtomEntry(Data2CMIS(newObj), newObj.Title, newObj.CreationDate, newObj.CreationDate, New List(Of String) From {newObj.Author}, False, False, "")
               ElseIf objType = TypeData.BaseTypeEnum.RootFolder Then
                  Dim newId As String = Guid.NewGuid.ToString
                  Dim tmpPath As String = parent.Path
                  If Not tmpPath.EndsWith("/") Then
                     tmpPath = tmpPath & "/"
                  End If
                  Dim newObj As New CMISSampleData(newId, _sampleTypes(TypeData.Folder1Type)) With {.Title = typedNameProp.Values(0), .Path = tmpPath & newId}
                  InnerUpdateProperties(parsedData, newObj)
                  parent.AddChild(newObj.Id, newObj)
                  _cmisSampleData.Add(newObj.Id, newObj)
                  Return GetAtomEntry(Data2CMIS(newObj), newObj.Title, newObj.CreationDate, newObj.CreationDate, New List(Of String) From {newObj.Author}, False, False, "")

               End If
            End If


         End If
      Else
         Dim idProp As Properties.CmisPropertyId = DirectCast(parsedData.GetPropertyByDefinitionId("cmis:objectId", False), Properties.CmisPropertyId)
         Dim tmpId As String = idProp.Values(0)
         _cmisSampleData(sourceFolderId).RemoveChildEntry(tmpId)
         _cmisSampleData(id).AddChild(tmpId, _cmisSampleData(tmpId))
         Return InnerGetObject(tmpId, False, False, "")
      End If
      Return Nothing
   End Function

   Public Function CreateRelationship(repositoryId As String, id As String, rawData As System.Xml.XmlDocument, parsedData As CMISObjectModel.CMISObjects.CMISReceiptObject) As CMISObjectModel.Atom.CMISAtomEntryCmisObject Implements CMISObjectModel.IProvider.CreateRelationship
      Dim newId As String = Guid.NewGuid.ToString


      Dim nameProp As Properties.ICMISProperty = parsedData.GetPropertyByDefinitionId("cmis:name", False)
      Dim name As String = ""
      If nameProp IsNot Nothing AndAlso nameProp.GetType Is GetType(Properties.CmisPropertyString) Then
         Dim typedNameProp As Properties.CmisPropertyString = DirectCast(nameProp, Properties.CmisPropertyString)
         name = typedNameProp.Values(0)
      End If
      Dim sourceIdProp As Properties.ICMISProperty = parsedData.GetPropertyByDefinitionId("cmis:sourceId", False)
      Dim targetIdProp As Properties.ICMISProperty = parsedData.GetPropertyByDefinitionId("cmis:targetId", False)
      If sourceIdProp IsNot Nothing AndAlso targetIdProp IsNot Nothing AndAlso sourceIdProp.GetType Is GetType(Properties.CmisPropertyId) AndAlso targetIdProp.GetType Is GetType(Properties.CmisPropertyId) Then
         Dim typedSourceIdProp As Properties.CmisPropertyId = DirectCast(parsedData.GetPropertyByDefinitionId("cmis:sourceId", False), Properties.CmisPropertyId)
         Dim typedTargetIdProp As Properties.CmisPropertyId = DirectCast(parsedData.GetPropertyByDefinitionId("cmis:targetId", False), Properties.CmisPropertyId)
         Dim sourceId As String = typedSourceIdProp.Values(0)
         Dim targetId As String = typedTargetIdProp.Values(0)
         Dim rel As New CMISSampleData(newId, _sampleTypes(TypeData.Relationship1Type)) With {.Title = name, .SourceId = sourceId, .TargetId = targetId}
         _cmisSampleData.Add(rel.Id, rel)
         _cmisSampleData(sourceId).Relationships.Add(rel.Id, rel)
         _cmisSampleData(targetId).Relationships.Add(rel.Id, rel)
         Return GetAtomEntry(Data2CMIS(rel), rel.Title, rel.CreationDate, rel.CreationDate, New List(Of String) From {rel.Author}, False, False, "")
      End If

      Return Nothing
   End Function

   Public Sub DeleteContentStream(repositoryId As String, id As String) Implements CMISObjectModel.IProvider.DeleteContentStream
      Dim obj As CMISSampleData = _cmisSampleData(id)
      obj.ContentStream = Nothing
      obj.Mimetype = Nothing
   End Sub

   Public Sub DeleteObject(repositoryId As String, id As String, allVersions As Boolean?) Implements CMISObjectModel.IProvider.DeleteObject
      CMISSampleData.RemoveChild(id)
      _cmisSampleData.Remove(id)
   End Sub

   Public Function DeleteTree(repositoryId As String, id As String, allVersions As Boolean?, continueOnFailure As Boolean?, unfileObjects As CMISObjectModel.Enums.UnfileObjectsEnum?) As CMISObjectModel.Enums.DeleteTreeResultEnum Implements CMISObjectModel.IProvider.DeleteTree
      Dim data As CMISSampleData = _cmisSampleData(id)
      CMISSampleData.RemoveChild(id)
      _cmisSampleData.Remove(id)
      DeleteTreeChildren(data.SortedChildren)
      Return Enums.DeleteTreeResultEnum.Ok
   End Function
   Private Sub DeleteTreeChildren(children As List(Of CMISSampleData))
      If children.Count > 0 Then
         For i As Integer = children.Count - 1 To 0 Step -1
            Dim child As CMISSampleData = children(i)
            CMISSampleData.RemoveChild(child.Id)
            _cmisSampleData.Remove(child.Id)
            If child.SortedChildren IsNot Nothing Then
               DeleteTreeChildren(child.SortedChildren)
            End If
         Next
      End If
   End Sub
   Public Function GetACL(repositoryId As String, id As String) As CMISObjectModel.CMISObjects.Acl Implements CMISObjectModel.IProvider.GetACL
      If EnableAllCapabilitiesForTCKTest Then
         Dim acl As New CMISObjectModel.CMISObjects.AccessControlList
         Dim retVal As New CMISObjectModel.CMISObjects.Acl
         retVal.ACL = New CMISObjectModel.CMISObjects.AccessControlList() {acl}
         Return retVal
      End If
      Throw New System.ServiceModel.Web.WebFaultException(Net.HttpStatusCode.NotImplemented)
   End Function

   Public Function GetAllowableActions(repositoryId As String, id As String) As CMISObjectModel.CMISObjects.AllowableActions Implements CMISObjectModel.IProvider.GetAllowableActions
      Return InnerGetObject(id, False, False, "").Object.AllowableActions
   End Function

   Public Function GetAllVersions(repositoryId As String, id As String, filter As String, includeAllowableActions As Boolean?) As CMISObjectModel.Atom.CMISAtomFeed(Of CMISObjectModel.CMISObjects.CmisObject) Implements CMISObjectModel.IProvider.GetAllVersions
      Throw New System.ServiceModel.Web.WebFaultException(Net.HttpStatusCode.NotImplemented)
   End Function

   Public Function GetAppliedPolicies(repositoryId As String, id As String, filter As String) As CMISObjectModel.Atom.CMISAtomFeed(Of CMISObjectModel.CMISObjects.CmisObject) Implements CMISObjectModel.IProvider.GetAppliedPolicies
      Return GetAtomFeed(New List(Of Atom.CMISAtomEntry(Of CMISObjects.CmisObject)), Guid.NewGuid.ToString, "GetAppliedPolicies", Now, New List(Of String), False, -1)
   End Function

   Public Function GetCheckedOutDocs(repositoryId As String, id As String, filter As String, maxItems As Integer?, skipCount As Integer?, renditionFilter As String, includeAllowableActions As Boolean?, includeRelationships As CMISObjectModel.Enums.IncludeRelationships?) As CMISObjectModel.Atom.CMISAtomFeed(Of CMISObjectModel.CMISObjects.CmisObject) Implements CMISObjectModel.IProvider.GetCheckedOutDocs
      Return GetAtomFeed(New List(Of Atom.CMISAtomEntry(Of CMISObjects.CmisObject)), Guid.NewGuid.ToString, "GetCheckedOutDocs", Now, New List(Of String), False, 0)
   End Function

   Public Function GetChildren(repositoryId As String, id As String, maxItems As Integer?, skipCount As Integer?, orderBy As String, filter As String, includeRelationships As CMISObjectModel.Enums.IncludeRelationships?, renditionFilter As String, includeAllowableActions As Boolean?, includePathSegment As Boolean?) As CMISObjectModel.Atom.CMISAtomFeed(Of CMISObjectModel.CMISObjects.CmisObject) Implements CMISObjectModel.IProvider.GetChildren
      Dim atomData As New List(Of Atom.CMISAtomEntry(Of CMISObjects.CmisObject))
      Dim data As CMISSampleData = _cmisSampleData(id)
      Dim children As List(Of CMISSampleData) = data.SortedChildren
      Dim tmpIncludePathSegment As Boolean = If(includePathSegment Is Nothing, False, includePathSegment.Value)
      Dim i As Integer = -1
      Dim hasMore As Boolean = False
      For Each child As CMISSampleData In children
         i = i + 1
         If i < skipCount Then
            Continue For
         End If
         If i - skipCount > maxItems - 1 Then
            hasMore = True
            Exit For
         End If
         Dim authors As New List(Of String) From {child.Author}

         atomData.Add(GetAtomEntry(Data2CMIS(child), child.Title, child.CreationDate, child.CreationDate, authors, tmpIncludePathSegment, False, ""))

      Next
      Return GetAtomFeed(atomData, Guid.NewGuid.ToString, "GetChildren", Now, New List(Of String), hasMore, children.Count)
   End Function

   Public Function GetContentChanges(repositoryId As String, filter As String, maxItems As Integer?, includeACL As Boolean?, includePolicyIds As Boolean?, includeProperties As Boolean?, changeLogToken As String) As CMISObjectModel.Atom.CMISAtomFeed(Of CMISObjectModel.CMISObjects.CmisObject) Implements CMISObjectModel.IProvider.GetContentChanges
      If EnableAllCapabilitiesForTCKTest Then
         Dim item As CMISSampleData = _cmisSampleData("SampleDocument1")
         Dim atomData As New List(Of Atom.CMISAtomEntry(Of CMISObjects.CmisObject))
         atomData.Add(GetAtomEntry(Data2CMIS(item), item.Title, item.CreationDate, item.CreationDate, New List(Of String), False, False, ""))
         Return GetAtomFeed(atomData, Guid.NewGuid.ToString, "GetChildren", Now, New List(Of String), False, 1)
      End If
      Throw New System.ServiceModel.Web.WebFaultException(Net.HttpStatusCode.NotImplemented)
   End Function

   Public Function GetContentStream(repositoryId As String, id As String, streamId As String) As CMISObjectModel.ContentStreamWrapper Implements CMISObjectModel.IProvider.GetContentStream
      Dim data As CMISSampleData = _cmisSampleData(id)
      If data.ContentStream Is Nothing Then
         Throw New ServiceModel.Web.WebFaultException(Net.HttpStatusCode.NoContent)
      Else
         Return New CMISObjectModel.ContentStreamWrapper(New IO.MemoryStream(data.ContentStream), data.Mimetype)
      End If
   End Function

   Public Function GetDescendants(repositoryId As String, id As String, filter As String, depth As Integer?, includeAllowableActions As Boolean?, includeRelationships As CMISObjectModel.Enums.IncludeRelationships?, renditionFilter As String, includePathSegment As Boolean?) As CMISObjectModel.Atom.CMISAtomFeed(Of CMISObjectModel.CMISObjects.CmisObject) Implements CMISObjectModel.IProvider.GetDescendants
      Dim data As New List(Of CMISSampleData)
      If id Is Nothing Then
         data.Add(_cmisSampleData("ROOTFOLDER"))
      Else
         data.AddRange(_cmisSampleData(id).SortedChildren)
      End If

      Dim items As New List(Of Atom.CMISAtomEntry(Of CMISObjects.CmisObject))
      Dim tmpIncludePathSegment As Boolean = If(includePathSegment Is Nothing, False, includePathSegment.Value)
      BuildDescendants(data, items, tmpIncludePathSegment, False)
      Return GetAtomFeed(items, Guid.NewGuid.ToString, "GetDescendants", Now, New List(Of String), False, -1)
   End Function
   Private Sub BuildDescendants(data As List(Of CMISSampleData), items As List(Of Atom.CMISAtomEntry(Of CMISObjects.CmisObject)), includePathSegment As Boolean, onlyFolder As Boolean)
      For Each t As CMISSampleData In data
         If onlyFolder AndAlso t.TypeData.BaseType <> TypeData.BaseTypeEnum.RootFolder Then
            Continue For
         End If
         Dim item As Atom.CMISAtomEntry(Of CMISObjects.CmisObject) = GetAtomEntry(Data2CMIS(t), t.Title, t.CreationDate, t.CreationDate, New List(Of String) From {t.Author}, includePathSegment, False, "")
         items.Add(item)
         If t.ChildrenCount > 0 Then
            item.Children = GetAtomFeed(New List(Of Atom.CMISAtomEntry(Of CMISObjects.CmisObject)), Guid.NewGuid.ToString, "GetDescendants", Now, New List(Of String), False, -1)
            BuildDescendants(t.SortedChildren.ToList, item.Children.Entries, includePathSegment, onlyFolder)
         End If
      Next
   End Sub
   Public Function GetFolderTree(repositoryId As String, id As String, filter As String, depth As Integer?, includeAllowableActions As Boolean?, includeRelationships As CMISObjectModel.Enums.IncludeRelationships?, renditionFilter As String) As CMISObjectModel.Atom.CMISAtomFeed(Of CMISObjectModel.CMISObjects.CmisObject) Implements CMISObjectModel.IProvider.GetFolderTree
      Dim data As New List(Of CMISSampleData)
      If id Is Nothing Then
         data.Add(_cmisSampleData("ROOTFOLDER"))
      Else
         data.AddRange(_cmisSampleData(id).SortedChildren)
      End If

      Dim items As New List(Of Atom.CMISAtomEntry(Of CMISObjects.CmisObject))
      BuildDescendants(data, items, False, True)
      Return GetAtomFeed(items, Guid.NewGuid.ToString, "GetDescendants", Now, New List(Of String), False, -1)
   End Function

   Public Function GetObject(repositoryId As String, id As String, pPwc As Boolean?, returnVersion As CMISObjectModel.Enums.ReturnVersionEnum?, filter As String, includeAllowableActions As Boolean?, includeRelationships As CMISObjectModel.Enums.IncludeRelationships?, renditionFilter As String, includePolicyIds As Boolean?, includeAcl As Boolean?) As CMISObjectModel.Atom.CMISAtomEntryCmisObject Implements CMISObjectModel.IProvider.GetObject
      Dim tmp As Atom.CMISAtomEntryCmisObject = InnerGetObject(id, False, False, "")
      If tmp Is Nothing Then
         Throw New ServiceModel.Web.WebFaultException(Net.HttpStatusCode.NotFound)
      End If
      Return tmp
   End Function

   Public Function GetObjectByPath(repositoryId As String, path As String, filter As String, includeAllowableActions As Boolean?, includeRelationships As CMISObjectModel.Enums.IncludeRelationships?, renditionFilter As String, includePolicyIds As Boolean?, includeACL As Boolean?) As CMISObjectModel.Atom.CMISAtomEntryCmisObject Implements CMISObjectModel.IProvider.GetObjectByPath
      If path.Equals("/") Then
         Return InnerGetObject("ROOTFOLDER", False, False, "")
      End If
      Dim parts() As String = path.Split("/"c)
      Return InnerGetObject(parts(parts.Count - 1), False, False, "")
   End Function


   Public Function GetObjectParents(repositoryId As String, id As String, filter As String, includeRelationships As CMISObjectModel.Enums.IncludeRelationships?, renditionFilter As String, includeAllowableActions As Boolean?, includeRelativePathSegment As Boolean?) As CMISObjectModel.Atom.CMISAtomFeed(Of CMISObjectModel.CMISObjects.CmisObject) Implements CMISObjectModel.IProvider.GetObjectParents
      Dim dataList As List(Of CMISSampleData) = CMISSampleData.FindParent(id)
      Dim atomData As New List(Of Atom.CMISAtomEntry(Of CMISObjects.CmisObject))
      Dim tmpincludeRelativePathSegment As Boolean = If(includeRelativePathSegment Is Nothing, False, includeRelativePathSegment.Value)
      For Each data As CMISSampleData In dataList
         Dim authors As New List(Of String) From {data.Author}
         atomData.Add(GetAtomEntry(Data2CMIS(data), data.Title, data.CreationDate, data.CreationDate, authors, False, tmpincludeRelativePathSegment, id))
      Next
      Return GetAtomFeed(atomData, Guid.NewGuid.ToString, "GetObjectParents", Now, New List(Of String), False, -1)
   End Function
#Region "Helper"
   Private Function InnerGetObject(id As String, includePathSegment As Boolean, includeRelativePathSegment As Boolean, requestId As String) As Atom.CMISAtomEntryCmisObject
      If Not _cmisSampleData.ContainsKey(id) Then
         Return Nothing
      End If
      Dim data As CMISSampleData = _cmisSampleData(id)
      Dim authors As New List(Of String) From {data.Author}
      Return GetAtomEntry(Data2CMIS(data), data.Title, data.CreationDate, data.CreationDate, authors, includePathSegment, includeRelativePathSegment, requestId)
   End Function
   Private Function Data2CMIS(data As CMISSampleData) As CMISObjects.CmisObject
      Select Case data.TypeData.BaseType
         Case TypeData.BaseTypeEnum.RootDocument
            Dim fileName() As String = Nothing
            If Not String.IsNullOrEmpty(data.FileName) Then
               fileName = New String() {data.FileName}
            End If
            Dim Mimetype() As String = Nothing
            If Not String.IsNullOrEmpty(data.Mimetype) Then
               Mimetype = New String() {data.Mimetype}
            End If
            Dim streamCount() As Int64 = Nothing
            Dim hasContent As Boolean = False
            If data.ContentStream IsNot Nothing Then
               streamCount = New Int64() {data.ContentStream.Count}
               If data.ContentStream.Count > 0 Then
                  hasContent = True
               End If
            End If
            Dim properties As New List(Of CMISObjectModel.Properties.ICMISProperty) From {
                           PropertyHelper.CreateCmisPropertyObjectId(New String() {data.Id}),
                           PropertyHelper.CreateCmisPropertyBaseTypeId(New String() {TypeData.RootDocumentType}),
                           PropertyHelper.CreateCmisPropertyCreatedBy(New String() {data.CreatedBy}),
                           PropertyHelper.CreateCmisPropertyCreationDate(New DateTimeOffset() {data.CreationDate}),
                           PropertyHelper.CreateCmisPropertyLastModificationDate(New DateTimeOffset() {data.CreationDate}),
                           PropertyHelper.CreateCmisPropertyLastModifiedBy(New String() {data.CreatedBy}), _
                           PropertyHelper.CreateCmisPropertyName(New String() {data.Title}),
                           PropertyHelper.CreateCmisPropertyObjectTypeId(New String() {data.TypeData.Definition.Id}),
                           PropertyHelper.CreateCmisPropertyCheckinComment(Nothing),
                           PropertyHelper.CreateCmisPropertyIsImmutable(New Boolean() {False}),
                           PropertyHelper.CreateCmisPropertyIsLatestVersion(New Boolean() {True}),
                           PropertyHelper.CreateCmisPropertyIsLatestMajorVersion(New Boolean() {True}),
                           PropertyHelper.CreateCmisPropertyIsMajorVersion(New Boolean() {True}),
                           PropertyHelper.CreateCmisPropertyContentStreamFileName(fileName),
                           PropertyHelper.CreateCmisPropertyContentStreamId(Nothing),
                           PropertyHelper.CreateCmisPropertyContentStreamLength(streamCount),
                           PropertyHelper.CreateCmisPropertyContentStreamMimeType(Mimetype),
                           PropertyHelper.CreateCmisPropertyVersionLabel(Nothing),
                           PropertyHelper.CreateCmisPropertyVersionSeriesId(New String() {data.Id}),
                           PropertyHelper.CreateCmisPropertyVersionSeriesCheckedOutBy(Nothing),
                           PropertyHelper.CreateCmisPropertyVersionSeriesCheckedOutId(Nothing),
                           PropertyHelper.CreateCmisPropertyIsVersionSeriesCheckedOut(New Boolean() {False}),
                           PropertyHelper.CreateCmisPropertyChangeToken(Nothing)}
            If data.TypeData.Type = TypeData.TypeEnum.Document1 Then
               properties.Add(PropertyHelper.CreateCmisPropertyValue1(New String() {data.Value1}))
               properties.Add(PropertyHelper.CreateCmisPropertyValue2(New String() {data.Value2}))
               properties.Add(PropertyHelper.CreateCmisPropertyValue3(New Decimal() {data.Value3}))
            End If
            Dim relations As New List(Of CMISObjects.CmisRelationshipObject)
            For Each item As CMISSampleData In data.Relationships.Values
               Dim rel As CMISObjects.CmisRelationshipObject = DirectCast(Data2CMIS(item), CMISObjects.CmisRelationshipObject)
               relations.Add(rel)
            Next

            Dim actions As New CMISObjects.AllowableActions With {.CanGetProperties = True, .CanGetObjectParents = True, .CanGetAllVersions = False, .CanGetContentStream = True, .CanDeleteContentStream = True, .CanUpdateProperties = True, .CanSetContentStream = True, .CanDeleteObject = True, .CanMoveObject = True, .CanCreateRelationship = True, .CanGetObjectRelationships = True}

            Return New CMISObjects.CmisDocumentObject(data.Id, properties.ToArray, TypeData.Document1Type, actions) With {.DisplayContentLink = hasContent, .Relationships = relations.ToArray}
         Case TypeData.BaseTypeEnum.RootFolder
            Dim parentId() As String = Nothing
            Dim parentId1 As String = ""
            Dim parentObj As List(Of CMISSampleData) = CMISSampleData.FindParent(data.Id)
            If parentObj.Count > 0 Then
               parentId1 = parentObj(0).Id
               parentId = New String() {parentId1}

            End If
            Dim properties As New List(Of CMISObjectModel.Properties.ICMISProperty) From {
                           PropertyHelper.CreateCmisPropertyBaseTypeId(New String() {TypeData.RootFolderType}),
                           PropertyHelper.CreateCmisPropertyCreatedBy(New String() {data.CreatedBy}),
                           PropertyHelper.CreateCmisPropertyCreationDate(New DateTimeOffset() {data.CreationDate}),
                           PropertyHelper.CreateCmisPropertyLastModificationDate(New DateTimeOffset() {data.CreationDate}),
                           PropertyHelper.CreateCmisPropertyLastModifiedBy(New String() {data.CreatedBy}), _
                           PropertyHelper.CreateCmisPropertyName(New String() {data.Title}),
                           PropertyHelper.CreateCmisPropertyObjectId(New String() {data.Id}),
                           PropertyHelper.CreateCmisPropertyObjectTypeId(New String() {data.TypeData.Definition.Id}),
                           PropertyHelper.CreateCmisPropertyParentId(parentId),
                           PropertyHelper.CreateCmisPropertyAllowedChildObjectTypeIds(New String() {TypeData.RootDocumentType, TypeData.RootFolderType}),
                           PropertyHelper.CreateCmisPropertyChangeToken(Nothing),
                           PropertyHelper.CreateCmisPropertyPath(New String() {data.Path})}
            Dim relations As New List(Of CMISObjects.CmisRelationshipObject)
            For Each item As CMISSampleData In data.Relationships.Values
               Dim rel As CMISObjects.CmisRelationshipObject = DirectCast(Data2CMIS(item), CMISObjects.CmisRelationshipObject)
               relations.Add(rel)
            Next
            Return New CMISObjects.CmisFolderObject(data.Id, properties.ToArray, TypeData.Folder1Type, New CMISObjects.AllowableActions With {.CanGetProperties = True, .CanGetFolderTree = True, .CanGetChildren = True, .CanGetObjectParents = parentObj.Count > 0, .CanGetFolderParent = parentObj.Count > 0, .CanUpdateProperties = Not data.TypeData.IsBaseType, .CanDeleteObject = False, .CanDeleteTree = Not data.TypeData.IsBaseType, .CanCreateRelationship = True, .CanGetObjectRelationships = True}, parentId1) With {.Relationships = relations.ToArray}
         Case TypeData.BaseTypeEnum.RootRelationship

            Dim properties As New List(Of CMISObjectModel.Properties.ICMISProperty) From {
                           PropertyHelper.CreateCmisPropertyBaseTypeId(New String() {TypeData.RootRelationshipType}),
                           PropertyHelper.CreateCmisPropertyCreatedBy(New String() {data.CreatedBy}),
                           PropertyHelper.CreateCmisPropertyCreationDate(New DateTimeOffset() {data.CreationDate}),
                           PropertyHelper.CreateCmisPropertyLastModificationDate(New DateTimeOffset() {data.CreationDate}),
                           PropertyHelper.CreateCmisPropertyLastModifiedBy(New String() {data.CreatedBy}), _
                           PropertyHelper.CreateCmisPropertyName(New String() {data.Title}),
                           PropertyHelper.CreateCmisPropertyObjectId(New String() {data.Id}),
                           PropertyHelper.CreateCmisPropertyObjectTypeId(New String() {data.TypeData.Definition.Id}),
                           PropertyHelper.CreateCmisPropertyChangeToken(Nothing),
                           PropertyHelper.CreateCmisPropertySourceId(New String() {data.SourceId}),
                             PropertyHelper.CreateCmisPropertyTargetId(New String() {data.TargetId})
                          }

            Return New CMISObjects.CmisRelationshipObject(data.Id, properties.ToArray, TypeData.Relationship1Type, New CMISObjects.AllowableActions With {.CanGetProperties = True, .CanGetFolderTree = True, .CanGetObjectParents = True, .CanDeleteObject = True}, data.SourceId, data.TargetId)

      End Select

      Return Nothing
   End Function
   Private Function GetAtomEntry(data As CMISObjects.CmisObject, title As String, creationDate As DateTime, lastUpdated As DateTime, authors As List(Of String), includePathSegment As Boolean, includeRelativePathSegment As Boolean, requestId As String) As Atom.CMISAtomEntryCmisObject
      Dim tmpAuthors As New List(Of System.ServiceModel.Syndication.SyndicationPerson)
      For Each author As String In authors
         tmpAuthors.Add(New System.ServiceModel.Syndication.SyndicationPerson(author))
      Next
      Dim pathSegment As String = ""
      If includePathSegment Then
         pathSegment = data.Id
      End If
      Dim relativePathSegment As String = ""
      If includeRelativePathSegment Then
         relativePathSegment = requestId
      End If
      Return New Atom.CMISAtomEntryCmisObject(data, data.Id, title, creationDate, lastUpdated, tmpAuthors, pathSegment, relativePathSegment)
   End Function
   Private Function GetAtomFeed(data As List(Of Atom.CMISAtomEntry(Of CMISObjects.CmisObject)), id As String, title As String, lastUpdated As DateTime, authors As List(Of String), hasMoreItems As Boolean, totalCount As Integer) As CMISObjectModel.Atom.CMISAtomFeed(Of CMISObjectModel.CMISObjects.CmisObject)
      Dim tmpAuthors As New List(Of System.ServiceModel.Syndication.SyndicationPerson)
      For Each author As String In authors
         tmpAuthors.Add(New System.ServiceModel.Syndication.SyndicationPerson(author))
      Next
      Return New CMISObjectModel.Atom.CMISAtomFeed(Of CMISObjectModel.CMISObjects.CmisObject)(data, id, title, lastUpdated, tmpAuthors, hasMoreItems, totalCount)
   End Function


   Private Function GetAtomEntry(data As TypeDefinitions.TypeDefinition, title As String, creationDate As DateTime, lastUpdated As DateTime, authors As List(Of String)) As Atom.CMISAtomEntryTypeDefinition
      Dim tmpAuthors As New List(Of System.ServiceModel.Syndication.SyndicationPerson)
      For Each author As String In authors
         tmpAuthors.Add(New System.ServiceModel.Syndication.SyndicationPerson(author))
      Next
      Return New Atom.CMISAtomEntryTypeDefinition(data, data.Id, title, creationDate, lastUpdated, tmpAuthors)
   End Function
   Private Function GetAtomFeed(data As List(Of Atom.CMISAtomEntry(Of TypeDefinitions.TypeDefinition)), id As String, title As String, lastUpdated As DateTime, authors As List(Of String)) As CMISObjectModel.Atom.CMISAtomFeed(Of TypeDefinitions.TypeDefinition)
      Dim tmpAuthors As New List(Of System.ServiceModel.Syndication.SyndicationPerson)
      For Each author As String In authors
         tmpAuthors.Add(New System.ServiceModel.Syndication.SyndicationPerson(author))
      Next
      Return New CMISObjectModel.Atom.CMISAtomFeed(Of TypeDefinitions.TypeDefinition)(data, id, title, lastUpdated, tmpAuthors, False, -1)
   End Function
#End Region
   Public Function GetObjectRelationships(repositoryId As String, id As String, typeId As String, includeSubRelationshipTypes As Boolean?, relationshipDirection As CMISObjectModel.Enums.RelationshipDirectionEnum?, maxItems As Integer?, skipCount As Integer?, filter As String, includeAllowableActions As Boolean?) As CMISObjectModel.Atom.CMISAtomFeed(Of CMISObjectModel.CMISObjects.CmisObject) Implements CMISObjectModel.IProvider.GetObjectRelationships


      Dim atomData As New List(Of Atom.CMISAtomEntry(Of CMISObjects.CmisObject))
      Dim data As CMISSampleData = _cmisSampleData(id)
      Dim children As List(Of CMISSampleData) = data.Relationships.Values.ToList
      Dim i As Integer = -1
      Dim hasMore As Boolean = False
      For Each child As CMISSampleData In children
         i = i + 1
         If i < skipCount Then
            Continue For
         End If
         If i - skipCount > maxItems - 1 Then
            hasMore = True
            Exit For
         End If
         Dim authors As New List(Of String) From {child.Author}

         atomData.Add(GetAtomEntry(Data2CMIS(child), child.Title, child.CreationDate, child.CreationDate, authors, False, False, ""))

      Next
      Return GetAtomFeed(atomData, Guid.NewGuid.ToString, "GetChGetObjectRelationshipsildren", Now, New List(Of String), hasMore, children.Count)
   End Function

   Public Function GetRepositories() As System.Collections.Generic.List(Of CMISObjectModel.ServiceDocument.RepositoryInfo) Implements CMISObjectModel.IProvider.GetRepositories
      Return New List(Of ServiceDocument.RepositoryInfo) From {GetRepository("")}
   End Function

   Public Function GetRepository(repositoryId As String) As CMISObjectModel.ServiceDocument.RepositoryInfo Implements CMISObjectModel.IProvider.GetRepository
      Dim rc As ServiceDocument.RepositoryCapabilities
      If EnableAllCapabilitiesForTCKTest Then
         rc = New ServiceDocument.RepositoryCapabilities() With { _
              .Acl = ServiceDocument.RepositoryCapabilities.CapabilityAcl.Discover, _
              .AllVersionsSearchable = True, _
              .Changes = ServiceDocument.RepositoryCapabilities.CapabilityChanges.Properties, _
              .ContentStreamUpdatability = ServiceDocument.RepositoryCapabilities.CapabilityContentStreamUpdates.Anytime, _
              .GetDescendants = True, _
              .GetFolderTree = True, _
              .Multifiling = True, _
              .PwcSearchable = True, _
              .PwcUpdatable = True, _
              .Query = ServiceDocument.RepositoryCapabilities.CapabilityQuery.BothCombined, _
              .Renditions = ServiceDocument.RepositoryCapabilities.CapabilityRendition.Read, _
              .Unfiling = True, _
              .VersionSpecificFiling = True, _
              .Join = ServiceDocument.RepositoryCapabilities.CapabilityJoin.InnerOnly}
      Else
         rc = New ServiceDocument.RepositoryCapabilities() With { _
              .Acl = ServiceDocument.RepositoryCapabilities.CapabilityAcl.None, _
              .AllVersionsSearchable = False, _
              .Changes = ServiceDocument.RepositoryCapabilities.CapabilityChanges.None, _
              .ContentStreamUpdatability = ServiceDocument.RepositoryCapabilities.CapabilityContentStreamUpdates.Anytime, _
              .GetDescendants = True, _
              .GetFolderTree = True, _
              .Multifiling = False, _
              .PwcSearchable = False, _
              .PwcUpdatable = False, _
              .Query = ServiceDocument.RepositoryCapabilities.CapabilityQuery.None, _
              .Renditions = ServiceDocument.RepositoryCapabilities.CapabilityRendition.None, _
              .Unfiling = False, _
              .VersionSpecificFiling = False, _
              .Join = ServiceDocument.RepositoryCapabilities.CapabilityJoin.None}
      End If
     


      Return New CMISObjectModel.ServiceDocument.RepositoryInfo() With { _
          .RepositoryId = "TestProvider", _
          .RepositoryName = "TestProvider! Demo only!", _
          .RepositoryDescription = "This is only a TestProvider! The TestProvider is not designed for running in a productive CMIS Client. It's only used for demonstrating the CMIS standard and the usage of the 'IProvider' interface.", _
          .VendorName = "Brügmann Software GmbH", _
          .ProductName = "VB.CMIS", _
          .ProductVersion = "1.0", _
          .RootFolderId = "ROOTFOLDER", _
          .LatestChangeLogToken = "", _
          .CmisVersionSupported = "1.0", _
          .ThinClientURI = "",
          .AclCapability = New ServiceDocument.AclCapability(),
          .Capabilities = rc
    }
   End Function

   Public Function GetTypeChildren(repositoryId As String, id As String, includePropertyDefinitions As Boolean?, maxItems As Integer?, skipCount As Integer?) As CMISObjectModel.Atom.CMISAtomFeed(Of CMISObjectModel.TypeDefinitions.TypeDefinition) Implements CMISObjectModel.IProvider.GetTypeChildren
      Dim atomData As New List(Of Atom.CMISAtomEntry(Of TypeDefinitions.TypeDefinition))
      Dim children As Dictionary(Of String, TypeData)

      If String.IsNullOrEmpty(id) Then
         children = (From sampleType As KeyValuePair(Of String, TypeData) In _sampleTypes
                     Where sampleType.Value.IsBaseType
                     Select sampleType).ToDictionary(Of String, TypeData)(Function(currentSampleType) currentSampleType.Key, Function(currentSampleType) currentSampleType.Value)

      Else
         Dim data As TypeData = _sampleTypes(id)
         children = data.Children
      End If

      For Each child As TypeData In children.Values
         Dim authors As New List(Of String) From {child.Author}
         atomData.Add(GetAtomEntry(child.Definition, child.Definition.DisplayName, child.CreationDate, child.CreationDate, New List(Of String)))
      Next
      Return GetAtomFeed(atomData, Guid.NewGuid.ToString, "GetTypeChildren", Now, New List(Of String))
   End Function

   Public Function GetTypeDefinition(repositoryId As String, id As String) As CMISObjectModel.Atom.CMISAtomEntryTypeDefinition Implements CMISObjectModel.IProvider.GetTypeDefinition
      Dim data As TypeData = _sampleTypes(id)
      Dim authors As New List(Of String) From {data.Author}
      Return GetAtomEntry(data.Definition, data.Definition.DisplayName, data.CreationDate, data.CreationDate, authors)
   End Function

   Public Function GetTypeDescendants(repositoryId As String, id As String, includePropertyDefinitions As Boolean?, depth As Integer?) As CMISObjectModel.Atom.CMISAtomFeed(Of CMISObjectModel.TypeDefinitions.TypeDefinition) Implements CMISObjectModel.IProvider.GetTypeDescendants
      Dim data As New List(Of TypeData)
      If id Is Nothing Then

         For Each t As TypeData In _sampleTypes.Values
            If t.IsBaseType Then
               data.Add(t)
            End If
         Next
      Else
         data.AddRange(_sampleTypes(id).Children.Values)
      End If

      Dim items As New List(Of Atom.CMISAtomEntry(Of TypeDefinitions.TypeDefinition))
      BuildTypeDescendants(data, items)
      Return GetAtomFeed(items, Guid.NewGuid.ToString, "GetTypeDescendants", Now, New List(Of String))
   End Function
   Private Sub BuildTypeDescendants(data As List(Of TypeData), items As List(Of Atom.CMISAtomEntry(Of TypeDefinitions.TypeDefinition)))
      For Each t As TypeData In data
         Dim item As Atom.CMISAtomEntry(Of TypeDefinitions.TypeDefinition) = GetAtomEntry(t.Definition, t.Definition.DisplayName, t.CreationDate, t.CreationDate, New List(Of String) From {t.Author})
         items.Add(item)
         If t.Children IsNot Nothing AndAlso t.Children.Count > 0 Then
            item.Children = GetAtomFeed(New List(Of Atom.CMISAtomEntry(Of TypeDefinitions.TypeDefinition)), Guid.NewGuid.ToString, "GetTypeDescendants", Now, New List(Of String))
            BuildTypeDescendants(t.Children.Values.ToList, item.Children.Entries)
         End If
      Next
   End Sub
   Public Function GetTypeParentId(repositoryId As String, id As String) As String Implements CMISObjectModel.IProvider.GetTypeParentId
      Dim dataList As List(Of TypeData) = TypeData.FindParent(id)
      If dataList.Count > 0 Then
         Return dataList(0).Definition.Id
      Else
         Return Nothing
      End If
   End Function

   Public Function GetUnfiled(repositoryId As String) As CMISObjectModel.Atom.CMISAtomFeed(Of CMISObjectModel.CMISObjects.CmisObject) Implements CMISObjectModel.IProvider.GetUnfiled
      Throw New System.ServiceModel.Web.WebFaultException(Net.HttpStatusCode.NotImplemented)
   End Function

   Public Sub Init(username As String) Implements CMISObjectModel.IProvider.Init

   End Sub

   Public Function IsUserValid(username As String, password As String) As Boolean Implements CMISObjectModel.IProvider.IsUserValid
      Return True
   End Function

   Public Function Query(repositoryId As String, q As String, searchAllVersions As Boolean?, maxItems As Integer?, skipCount As Integer?, includeAllowableActions As Boolean?, includeRelationships As CMISObjectModel.Enums.IncludeRelationships?) As CMISObjectModel.Atom.CMISAtomFeed(Of CMISObjectModel.CMISObjects.CmisObject) Implements CMISObjectModel.IProvider.Query

      If EnableAllCapabilitiesForTCKTest Then
         Dim item As CMISSampleData = _cmisSampleData("SampleDocument1")
         Dim atomData As New List(Of Atom.CMISAtomEntry(Of CMISObjects.CmisObject))
         atomData.Add(GetAtomEntry(Data2CMIS(item), item.Title, item.CreationDate, item.CreationDate, New List(Of String), False, False, ""))
         Return GetAtomFeed(atomData, Guid.NewGuid.ToString, "GetChildren", Now, New List(Of String), False, 1)
      End If
      Throw New System.ServiceModel.Web.WebFaultException(Net.HttpStatusCode.NotImplemented)
   End Function

   Public Function Query(repositoryId As String, rawData As System.Xml.XmlDocument, parsedData As CMISObjectModel.Query) As CMISObjectModel.Atom.CMISAtomFeed(Of CMISObjectModel.CMISObjects.CmisObject) Implements CMISObjectModel.IProvider.Query

      If EnableAllCapabilitiesForTCKTest Then
         Dim item As CMISSampleData = _cmisSampleData("SampleDocument1")
         Dim atomData As New List(Of Atom.CMISAtomEntry(Of CMISObjects.CmisObject))
         atomData.Add(GetAtomEntry(Data2CMIS(item), item.Title, item.CreationDate, item.CreationDate, New List(Of String), False, False, ""))
         Return GetAtomFeed(atomData, Guid.NewGuid.ToString, "GetChildren", Now, New List(Of String), False, 1)
      End If

      Throw New System.ServiceModel.Web.WebFaultException(Net.HttpStatusCode.NotImplemented)
   End Function

   Public Function RemoveObjectFromFolder(repositoryId As String, removeFrom As String, rawData As System.Xml.XmlDocument, parsedData As CMISObjectModel.CMISObjects.CMISReceiptObject) As CMISObjectModel.Atom.CMISAtomEntryCmisObject Implements CMISObjectModel.IProvider.RemoveObjectFromFolder
      If EnableAllCapabilitiesForTCKTest Then
         Dim item As CMISSampleData = _cmisSampleData("SampleDocument1")
         Return GetAtomEntry(Data2CMIS(item), item.Title, item.CreationDate, item.CreationDate, New List(Of String), False, False, "")
      End If

      Throw New System.ServiceModel.Web.WebFaultException(Net.HttpStatusCode.NotImplemented)
   End Function

   Public Sub RemovePolicy(repositoryId As String, id As String) Implements CMISObjectModel.IProvider.RemovePolicy
      If EnableAllCapabilitiesForTCKTest Then
         Exit Sub
      End If
      Throw New System.ServiceModel.Web.WebFaultException(Net.HttpStatusCode.NotImplemented)
   End Sub

   Public Function SetContentStream(repositoryId As String, id As String, overwriteFlag As Boolean?, data As System.IO.Stream) As CMISObjectModel.Enums.SetContentStreamResultEnum Implements CMISObjectModel.IProvider.SetContentStream
      Dim obj As CMISSampleData = _cmisSampleData(id)
      Dim oldCount As Integer = If(obj.ContentStream Is Nothing, 0, obj.ContentStream.Count)
      Using stream As New IO.MemoryStream()
         data.CopyTo(stream)
         stream.Flush()
         obj.ContentStream = stream.ToArray
      End Using
      If obj.ContentStream.Count > 0 Then
         If oldCount < 1 Then
            Return Enums.SetContentStreamResultEnum.ResourceCreated
         Else
            Return Enums.SetContentStreamResultEnum.HasContent
         End If
      Else
         obj.ContentStream = Nothing
         Return Enums.SetContentStreamResultEnum.HasNoContent
      End If
   End Function

   Public Function UpdateProperties(repositoryId As String, id As String, major As Boolean?, checkIn As Boolean?, checkinComment As String, rawData As System.Xml.XmlDocument, parseData As CMISObjectModel.CMISObjects.CMISReceiptObject) As CMISObjectModel.Atom.CMISAtomEntryCmisObject Implements CMISObjectModel.IProvider.UpdateProperties
      InnerUpdateProperties(parseData, _cmisSampleData(id))
      Return InnerGetObject(id, False, False, "")
   End Function
   Private Sub InnerUpdateProperties(sourceObj As CMISObjects.CMISReceiptObject, destionationObj As CMISSampleData)
      Dim data As GetPropDataResult(Of String) = GetPropStrData(sourceObj, "Value1")
      If data.IsSet Then
         destionationObj.Value1 = data.Val
      End If
      data = GetPropStrData(sourceObj, "Value2")
      If data.IsSet Then
         destionationObj.Value2 = data.Val
      End If
      Dim data1 As GetPropDataResult(Of Decimal) = GetPropDecimalData(sourceObj, "Value3")
      If data1.IsSet Then
         destionationObj.Value3 = data1.Val
      End If
      data = GetPropStrData(sourceObj, "cmis:name")
      If data.IsSet Then
         destionationObj.Title = data.Val
      End If
    
   End Sub
   Private Class GetPropDataResult(Of T)
      Public Property Val As T
      Public Property IsSet As Boolean = False
   End Class
   Private Function GetPropStrData(sourceObj As CMISObjects.CMISReceiptObject, propName As String) As GetPropDataResult(Of String)
      Dim prop As Properties.ICMISProperty = sourceObj.GetPropertyByDefinitionId(propName)
      If prop IsNot Nothing Then
         Dim tProp As Properties.CmisPropertyString = DirectCast(prop, Properties.CmisPropertyString)
         If tProp.Values Is Nothing OrElse tProp.Values.Count < 1 Then
            Return New GetPropDataResult(Of String) With {.IsSet = True}
         Else
            Return New GetPropDataResult(Of String) With {.IsSet = True, .Val = tProp.Values(0)}
         End If
      End If
      Return New GetPropDataResult(Of String)
   End Function
   Private Function GetPropDecimalData(sourceObj As CMISObjects.CMISReceiptObject, propName As String) As GetPropDataResult(Of Decimal)
      Dim prop As Properties.ICMISProperty = sourceObj.GetPropertyByDefinitionId(propName)
      If prop IsNot Nothing Then
         Dim tProp As Properties.CmisPropertyDecimal = DirectCast(prop, Properties.CmisPropertyDecimal)
         If tProp.Values Is Nothing OrElse tProp.Values.Count < 1 Then
            Return New GetPropDataResult(Of Decimal) With {.IsSet = True}
         Else
            Return New GetPropDataResult(Of Decimal) With {.IsSet = True, .Val = tProp.Values(0)}
         End If
      End If
      Return New GetPropDataResult(Of Decimal)
   End Function
End Class
